package cn.wangqi.personal.sql;


import cn.wangqi.personal.util.StringUtil;
import org.springframework.util.CollectionUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MapperUtil {
    private String jdbc;
    private String userName = "root";
    private String password = "root";
    private String[] tableNames;
    private String outPath;
    private String javaPath;
    private String packages;
    private String driver = "com.mysql.jdbc.Driver";
    private String jdbcUrl = "jdbc:mysql://localhost:3306/personal";
    private String daoPackage;
    private String controllerPackage;
    private String servicePackage;

    public void init(String jdbc, String userName, String password, String[] tableNames, String outputPath, String javaPath, String pack, String daoPackage, String servicePackage, String controllerPackage) {
        this.jdbc = jdbc;
        this.userName = userName;
        this.password = password;
        this.tableNames = tableNames;
        if (StringUtil.isEmpty(outputPath)) {
            this.outPath = System.getProperty("user.dir") + "/src/main/resources/mapper/";
        } else {
            this.outPath = outputPath;
        }
        if (StringUtil.isEmpty(javaPath)) {
            this.outPath = System.getProperty("user.dir") + "/src/main/resources/mapper/";
        } else {
            this.javaPath = javaPath;
        }
        this.packages = pack;
        this.daoPackage = daoPackage;
        this.servicePackage = servicePackage;
        this.controllerPackage = controllerPackage;
    }

    public void init(String[] tableNames, String mapperPath, String javaPath, String pack) {
        init(jdbcUrl, userName, password, tableNames, mapperPath, javaPath, pack, null, null, null);
    }

    private void init(String[] tableNames) {
        String path = System.getProperty("user.dir") + "/src/main/resources/mapper/";
        init(jdbcUrl, userName, password, tableNames, path, path, "", null, null, null);
    }

    public void generate(String[] tableNames) throws SQLException, ClassNotFoundException, IOException {
        init(tableNames);
        Connection connection = getConnection();
        DatabaseMetaData metaData = connection.getMetaData();
        if (tableNames == null) {
            return;
        }
        generate0(metaData);
        connection.close();

    }

    public void generate(String[] tableNames, String mapperPath, String javaPath, String pack, String daoPackage, String servicePackage, String controllerPackage) throws SQLException, ClassNotFoundException, IOException {
        init(jdbcUrl, userName, password, tableNames, mapperPath, javaPath, pack, daoPackage, servicePackage, controllerPackage);
        Connection connection = getConnection();
        DatabaseMetaData metaData = connection.getMetaData();
        if (tableNames == null) {
            return;
        }
        generate0(metaData);
        connection.close();

    }

    private Connection getConnection() throws ClassNotFoundException, SQLException {
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(jdbc, userName, password);
        return conn;
    }

    private void generate0(DatabaseMetaData metaData) throws SQLException, IOException {
        for (String table : tableNames) {
            ResultSet resultKey = metaData.getPrimaryKeys(null, null, table);

            //获取主键
            List<String> keys = generate4(resultKey);
            ResultSet tableRet = metaData.getColumns(null, "%", table, "%");

            //获取数据表的列
            List<String> column = generate1(tableRet);
            for (String k : keys) {
                for (String c : column) {
                    if (c.equals(k)) {
                        column.remove(c);
                        break;
                    }
                }
            }
            generate2(keys, column, table);
            tableRet = metaData.getColumns(null, "%", table, "%");
            generate5(tableRet, table);
        }

    }

    private List<String> generate4(ResultSet resultSet) throws SQLException {
        List<String> column = new ArrayList();
        while (resultSet.next()) {
            column.add(resultSet.getObject(4).toString());
        }
        return column;
    }

    private void generate5(ResultSet resultSet, String table) throws SQLException, IOException {


        String[] tableName = table.split("_");
        if (tableName == null || tableName.length == 0) {
            return;
        }
        String id = "";//类名
        if (tableName.length > 1) {
            for (int i = 1; i < tableName.length; i++) {
                id = id + tableName[i].substring(0, 1).toUpperCase() + tableName[i].substring(1);
            }
        } else {
            return;
        }
        File file = new File(javaPath, id.substring(0, 1).toUpperCase() + id.substring(1) + ".java");
        if (!file.exists()) {
            file.createNewFile();
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date d = new Date();
        String date = sdf.format(d);
        BufferedWriter outputStream = new BufferedWriter(new FileWriter(file));
        outputStream.write("package " + packages);
        outputStream.write(";\n\nimport java.io.Serializable;\nimport java.util.Date;\nimport java.math.BigDecimal;\n");
        outputStream.write("\n\n");
        outputStream.write("/**\n *created by " + System.getProperty("user.name") + "  " + date + "\n   实体：" + id + "\n */\n");
        outputStream.write("public class " + id.substring(0, 1).toUpperCase() + id.substring(1) + " implements Serializable{\n");
        outputStream.write("    private static final long serialVersionUID = 1L;\n");
        List<NamePair> typeName = new ArrayList();
        while (resultSet.next()) {
            String cName = getPropertiesValue(resultSet.getString("COLUMN_NAME").toLowerCase());
            String type = resultSet.getString("TYPE_NAME").toLowerCase();
            if (StringUtil.isNotEmpty(resultSet.getString("REMARKS"))) {
                outputStream.write("\n    //" + resultSet.getString("REMARKS") + "\n");
            } else {
                outputStream.write("\n");

            }
            outputStream.write("    private " + typeDif(type) + " " + cName + ";\n");
            typeName.add(new NamePair(cName, typeDif(type)));
        }

        if (typeName != null && typeName.size() > 0) {
            for (NamePair namePair : typeName) {
                outputStream.write("\n    public void set" + namePair.key.substring(0, 1).toUpperCase() + namePair.key.substring(1) + "(" + namePair.value + " " + namePair.key + "){\n        this." + namePair.key + " = " + namePair.key + ";\n    }\n\n");
                outputStream.write("    public " + namePair.value + " get" + namePair.key.substring(0, 1).toUpperCase() + namePair.key.substring(1) + "(){\n        return this." + namePair.key + ";\n    }\n");
            }

        }
        outputStream.write("\n}");
        outputStream.close();
    }

    private void generateDao(String domain) throws IOException {
        if (daoPackage == null || daoPackage == "") {
            return;
        }
        File file = new File(daoPackage, domain + "Dao.java");
        if (!file.exists()) {
            file.createNewFile();
        }
        BufferedWriter outputStream = new BufferedWriter(new FileWriter(file));
        String p = getPackage(daoPackage);
        String d = packages + "." + domain;
        outputStream.write("package " + p + ";\n\n");
        outputStream.write("import org.mybatis.spring.SqlSessionTemplate;\n");
        outputStream.write("import " + d + ";\n");
        outputStream.write("import org.springframework.stereotype.Repository;\n");
        outputStream.write("import java.util.HashMap;\n");
        outputStream.write("import java.util.List;\n");
        outputStream.write("import cn.wangqi.personal.util.Page;\n");
        outputStream.write("import org.apache.log4j.Logger;\n");
        outputStream.write("import java.util.Map;\n");
        outputStream.write("import javax.annotation.Resource;\n");
        outputStream.write("\n\n");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date ds = new Date();
        String date = sdf.format(ds);
        String var = domain.substring(0, 1).toLowerCase() + domain.substring(1);
        outputStream.write("/**\n *created by " + System.getProperty("user.name") + "  " + date + "\n */\n");
        outputStream.write("@Repository\n");
        outputStream.write("public class " + domain + "Dao{\n");
        outputStream.write("    private final String NAMESPACE = this.getClass().getName() + \".\";\n");
        outputStream.write("    private Logger logger = Logger.getLogger(" + domain + "Dao.class);\n");
        outputStream.write("    @Resource\n");
        outputStream.write("    protected SqlSessionTemplate mainSqlSession;\n");
        outputStream.write("    public void save" + domain + "(" + domain + " " + var + ") {\n" +
                "        mainSqlSession.insert(NAMESPACE + \"save" + domain + "\", " + var + ");\n" +
                "    }\n\n");

        outputStream.write("    public void save" + domain + "(List<" + domain + "> " + var + ") {\n" +
                "        mainSqlSession.insert(NAMESPACE + \"save" + domain + "List\", " + var + ");\n" +
                "    }\n\n");

        outputStream.write("    public void delete" + domain + "ById(int " + var + "Id) {\n" +
                "        mainSqlSession.delete(NAMESPACE + \"delete" + domain + "ById\", " + var + "Id);\n" +
                "    }\n\n");
        outputStream.write("    public " + domain + " find" + domain + "ById(int " + var + "Id){\n" +
                "        return mainSqlSession.selectOne(NAMESPACE + \"find" + domain + "ById\", " + var + "Id);\n" +
                "    }\n\n");
        outputStream.write("    public List<" + domain + "> list" + domain + "(int " + var + "Id, Page page){\n" +
                "        Map<String, Object> params = new HashMap<>();\n" +
                "        params.put(\"page\",page);\n"  +
                "        return mainSqlSession.selectList(NAMESPACE + \"list" + domain + "\", params);\n" +
                "    }\n\n");
        outputStream.write("    public int count" + domain + "(){\n" +
                "        Map<String, Object> params = new HashMap<>();\n" +
                "        return mainSqlSession.selectOne(NAMESPACE + \"total" + domain + "\",params);\n" +
                "    }\n\n");
        outputStream.write("    public void update" + domain + "(" + domain + " " + var + "){\n" +
                "        mainSqlSession.update(NAMESPACE + \"update" + domain + "\", " + var + ");\n" +
                "    }\n\n");
        outputStream.write("}\n");
        outputStream.close();
    }

    private void generateService(String domain) throws IOException {
        if (servicePackage == null || servicePackage == "") {
            return;
        }
        File file = new File(servicePackage, domain + "Service.java");
        if (!file.exists()) {
            file.createNewFile();
        }
        BufferedWriter outputStream = new BufferedWriter(new FileWriter(file));
        String p = getPackage(servicePackage);
        String d = packages + "." + domain;
        String daop = getPackage(daoPackage) + "." + domain + "Dao";
        outputStream.write("package " + p + ";\n\n");
        outputStream.write("import " + d + ";\n");
        outputStream.write("import " + p.substring(0, p.length() - 5)+ ".I" + domain + "Service;\n");
        outputStream.write("import cn.wangqi.personal.util.Page;\n");
        outputStream.write("import org.springframework.stereotype.Service;\n");
        outputStream.write("import java.util.HashMap;\n");
        outputStream.write("import " + daop + ";\n");
        outputStream.write("import java.util.List;\n");
        outputStream.write("import java.util.Map;\n");
        outputStream.write("import javax.annotation.Resource;\n");
        outputStream.write("\n\n");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date ds = new Date();
        String date = sdf.format(ds);
        String var = domain.substring(0, 1).toLowerCase() + domain.substring(1);
        outputStream.write("/**\n *created by " + System.getProperty("user.name") + "  " + date + "\n */\n");
        outputStream.write("@Service\n");
        outputStream.write("public class " + domain + "Service implements I" + domain + "Service{\n");
        outputStream.write("    @Resource\n");
        outputStream.write("    private " + domain + "Dao " + var + "Dao;\n");
        outputStream.write("    public void save" + domain + "(" + domain + " " + var + "){\n" +
                "        " + var + "Dao.save" + domain + "(" + var + ");\n" +
                "    }\n\n");
        outputStream.write("    public void delete" + domain + "(int " + var + "Id){\n" +
                "        " + var + "Dao.delete" + domain + "ById(" + var + "Id);\n" +
                "    }\n\n");
        outputStream.write("    public " + domain + " find" + domain + "ById(int " + var + "Id){\n" +
                "        return " + var + "Dao.find" + domain + "ById(" + var + "Id);\n" +
                "    }\n\n");
        outputStream.write("    public List<" + domain + "> list" + domain + "(int " + var + "Id, Page page){\n" +
                "        return " + var + "Dao.list" + domain + "(" + var + "Id, page);\n" +
                "    }\n\n");

        outputStream.write("    public int totalCount(){\n" +
                "        return " + var + "Dao.count" + domain + "();\n" +
                "    }\n\n");
        outputStream.write("    public void update" + domain + "(" + domain + " " + var + "){\n" +
                "        " + var + "Dao.update" + domain + "(" + var + ");\n" +
                "    }\n\n");
        outputStream.write("}\n");
        outputStream.close();
        generateInterface(domain);
    }

    private void generateInterface(String domain) throws IOException {


        if (servicePackage == null || servicePackage == "") {
            return;
        }
        String iPage = servicePackage.substring(0, servicePackage.length() - 5);
        File file = new File(iPage, "I" + domain + "Service.java");
        if (!file.exists()) {
            file.createNewFile();
        }
        BufferedWriter outputStream = new BufferedWriter(new FileWriter(file));
        String p = getPackage(iPage);
        String d = packages + "." + domain;
        outputStream.write("package " + p + ";\n\n");
        outputStream.write("import " + d + ";\n");
        outputStream.write("import cn.wangqi.personal.util.Page;\n");
        outputStream.write("import java.util.HashMap;\n");
        outputStream.write("import java.util.List;\n");
        outputStream.write("import java.util.Map;\n");
        outputStream.write("\n\n");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date ds = new Date();
        String date = sdf.format(ds);
        String var = domain.substring(0, 1).toLowerCase() + domain.substring(1);
        outputStream.write("/**\n *created by " + System.getProperty("user.name") + "  " + date + "\n */\n");
        outputStream.write("public interface I" + domain + "Service{\n");
        outputStream.write("    void save" + domain + "(" + domain + " " + var + ");\n");

        outputStream.write("    void delete" + domain + "(int " + var + "Id);\n\n");
        outputStream.write("    " + domain + " find" + domain + "ById(int id);\n\n");
        outputStream.write("    List<" + domain + "> list" + domain + "(int " + var + "Id, Page page);\n\n");

        outputStream.write("    int totalCount();\n\n");
        outputStream.write("    void update" + domain + "(" + domain + " " + var + ");\n\n");
        outputStream.write("}\n");
        outputStream.close();
    }


    private void generateController(String domain) throws IOException {
        if (controllerPackage == null || controllerPackage == "") {
            return;
        }
        if (servicePackage == null || servicePackage == "") {
            return;
        }
        File file = new File(controllerPackage, domain + "Controller.java");
        if (!file.exists()) {
            file.createNewFile();
        }
        BufferedWriter outputStream = new BufferedWriter(new FileWriter(file));
        String p = getPackage(controllerPackage);
        String d = packages + "." + domain;
        String serpa;
        serpa = getPackage(servicePackage).substring(0, getPackage(servicePackage).length() - 5) + ".I" + domain + "Service";
        outputStream.write("package " + p + ";\n\n");
        outputStream.write("import " + d + ";\n");
        outputStream.write("import cn.wangqi.personal.util.Page;\n");
        outputStream.write("import org.springframework.stereotype.Controller;\n");
        outputStream.write("import " + serpa + ";\n");
        outputStream.write("import java.util.HashMap;\n");
        outputStream.write("import java.io.Serializable;\n");
        outputStream.write("import org.apache.log4j.Logger;\n");
        outputStream.write("import org.springframework.ui.ModelMap;\n");
        outputStream.write("import org.springframework.web.bind.annotation.ResponseBody;\n");
        outputStream.write("import java.util.List;\n");
        outputStream.write("import com.ytx.learning.admin.common.BaseController;\n");
        outputStream.write("import org.springframework.web.bind.annotation.RequestMapping;\n");
        outputStream.write("import java.util.Map;\n");
        outputStream.write("import javax.annotation.Resource;\n");
        outputStream.write("\n\n");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date ds = new Date();
        String date = sdf.format(ds);
        String var = domain.substring(0, 1).toLowerCase() + domain.substring(1);
        outputStream.write("/**\n *created by " + System.getProperty("user.name") + "  " + date + "\n */\n");
        outputStream.write("@Controller\n");
        outputStream.write("@RequestMapping(\"" + var + "\")\n");
        outputStream.write("public class " + domain + "Controller extends BaseController{\n");
        outputStream.write("    private Logger logger = Logger.getLogger(" + domain + "Controller.class);\n");
        outputStream.write("    @Resource\n");
        outputStream.write("    private I" + domain + "Service " + var + "Service;\n");

        outputStream.write("    @RequestMapping(\"index.html\")\n");
        outputStream.write("    public String index(ModelMap map){\n    map.put(\"code\",\"\")\n" +
                "     return \"\";}");


        outputStream.write("    @RequestMapping(\"save" + domain + ".html\")\n" +
                "    @ResponseBody\n");
        outputStream.write("    public String save" + domain + "(" + domain + " " + var + "){\n" +
                "        try {\n" +
                "        " + var + "Service.save" + domain + "(" + var + ");\n" +
                "            return this.buildSuccessResponse(" + var + ");\n" +
                "        } catch (Exception e) {\n" +
                "            logger.error(e.getMessage(), e);\n" +
                "            return this.buildErrorResponse(e.getMessage());\n" +
                "        }" +
                "    }\n\n");
        outputStream.write("    @RequestMapping(\"delete" + domain + "ById.html\")\n" +
                "    @ResponseBody\n");
        outputStream.write("    public String delete" + domain + "(int " + var + "Id){\n" +
                "       try {\n" +
                "        " + var + "Service.delete" + domain + "(" + var + "Id);\n" +
                "            return this.buildSuccessResponse();\n" +
                "        } catch (Exception e) {\n" +
                "            logger.error(e.getMessage(), e);\n" +
                "            return this.buildErrorResponse(e.getMessage());\n" +
                "        }" +
                "    }\n\n");
        outputStream.write("    @RequestMapping(\"find" + domain + "ById.html\")\n" +
                "    @ResponseBody\n");
        outputStream.write("    public String find" + domain + "ById(int " + var + "Id){\n" +
                "       try {\n" +
                "            " + domain + " " + var + " = " + var + "Service.find" + domain + "ById(" + var + "Id);\n" +
                "            return this.buildSuccessResponse(" + var + ");\n" +
                "        } catch (Exception e) {\n" +
                "            logger.error(e.getMessage(), e);\n" +
                "            return this.buildErrorResponse(e.getMessage());\n" +
                "        }\n" +
                "    }\n\n");

        outputStream.write("@RequestMapping(\"list" +domain + ".html\")\n" +
                "    @ResponseBody\n");
        outputStream.write("    public String list" + domain+"(int currentPage){\n" +
                "     Page page = new Page((currentPage - 1)* 10, 10);\n" +
                "        //return " + var + "Service.list" + domain +"(page);\n" +
                "        return null;\n" +
                "    }\n\n");

        outputStream.write("@RequestMapping(\"update" + domain + ".html\")\n" +
                "    @ResponseBody\n");
        outputStream.write("    public String update" + domain + "(" + domain + " " + var + "){\n" +
                "try {\n" +
                "            " + var + "Service.update" + domain + "(" + var + ");\n" +
                "            return this.buildSuccessResponse(" + var + ");\n" +
                "        } catch (Exception e) {\n" +
                "            logger.error(e.getMessage(), e);\n" +
                "            return this.buildErrorResponse(e.getMessage());\n" +
                "        }\n" +
                "    }\n\n");

        outputStream.write("}\n");
        outputStream.close();
    }

    private List<String> generate1(ResultSet resultSet) throws SQLException {
        List<String> column = new ArrayList<>();
        while (resultSet.next()) {
            column.add(resultSet.getString("COLUMN_NAME").toLowerCase());
        }
        return column;
    }

    private void generate2(List<String> key, List<String> column, String table) throws IOException {
        String[] tableName = table.split("_");
        if (tableName == null || tableName.length == 0) {
            return;
        }
        String id = "";
        if (tableName.length > 1) {
            for (int i = 1; i < tableName.length; i++) {
                id = id + tableName[i].substring(0, 1).toUpperCase() + tableName[i].substring(1);
            }
        } else {
            return;
        }
        String namespace = "";
        if (daoPackage != null && daoPackage != "") {
            namespace = getPackage(daoPackage) + "." + id + "Dao";
        } else {
            namespace = packages + "." + id;
        }
        String name = id;
        String resultMap = name.substring(0, 1).toLowerCase() + name.substring(1);
        String head = "<!DOCTYPE mapper\n" +
                "        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n" +
                "        \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">";
        String head1 = "<mapper namespace=\"" + namespace + "\">";
        String head2 = "<resultMap id=\"" + resultMap + "\" type=\"" + packages + "." + name + "\">";
        File file = new File(outPath, name + ".xml");
        if (!file.exists()) {
            file.createNewFile();
        }
        BufferedWriter outputStream = new BufferedWriter(new FileWriter(file));
        outputStream.write(head);
        outputStream.newLine();
        outputStream.write(head1);
        outputStream.newLine();
        outputStream.write(head2);
        List<String> properties = new ArrayList<>();

        for (String k : key) {
            String p = getPropertiesValue(k);
            properties.add(p);
            String keyV = " <id column=\"" + k + "\" property=\"" + p + "\"/>";
            outputStream.write(keyV);
            outputStream.newLine();
        }
        for (String k : column) {
            String p = getPropertiesValue(k);
            properties.add(p);
            String keyV = " <result column=\"" + k + "\" property=\"" + p + "\"/>";
            outputStream.write(keyV);
            outputStream.newLine();
        }

        outputStream.write(" </resultMap>");
        outputStream.newLine();
        String sql = "   <sql id=\"column\">\n   ";
        StringBuilder sql1 = new StringBuilder();
        sql1.append(sql);
        for (int i = 0; i < key.size(); i++) {
            if (i == 0) {
                sql1.append(key.get(i));
            } else {
                sql1.append("," + key.get(i));
            }
        }
        for (int j = 0; j < column.size(); j++) {
            if (j == 0 && CollectionUtils.isEmpty(key)) {
                sql1.append(column.get(j));
            } else {
                sql1.append("," + column.get(j));
            }
        }
        sql1.append("\n    </sql>");
        outputStream.write(sql1.toString());
        outputStream.newLine();
        outputStream.write("  <insert id=\"save" + name + "\" parameterType=\"" + packages + "." + name + "\">\n");
        outputStream.write("    insert into " + table + "(<include refid=\"column\"></include>) values(\n");
        outputStream.write(toStringList(properties));
        outputStream.write("   )\n</insert>");
        outputStream.newLine();

        outputStream.write("  <insert id=\"save" + name + "List\" parameterType=\"" + packages + "." + name + "\">\n");
        outputStream.write("     insert into " + table + "(<include refid=\"column\"></include>) values\n");
        outputStream.write("     <foreach collection=\"list\" separator=\",\" item=\"data\">\n");
        outputStream.write("        " + toForeachStringList(properties));
        outputStream.write("     \n</foreach>");
        outputStream.write("  \n</insert>");
        outputStream.newLine();

        outputStream.write("  <select id=\"find" + name + "ById\" parameterType=\"map\" resultMap=\"" + id.substring(0, 1).toLowerCase() + id.substring(1) + "\">\n");
        outputStream.write("     SELECT <include refid=\"column\"></include>  from " + table + " where id=#{id}");
        outputStream.write("  </select>");
        outputStream.newLine();


        outputStream.write("  <select id=\"list" + name + "\" parameterType=\"map\" resultMap=\"" + id.substring(0, 1).toLowerCase() + id.substring(1) + "\">\n");
        outputStream.write("     SELECT <include refid=\"column\"></include>  from " + table);
        outputStream.write("     <if test=\"page != null\">\n");
        outputStream.write("        limit #{page.start}, #{page.pageSize}\n");
        outputStream.write("     </if>\n");
        outputStream.write("  </select>");
        outputStream.newLine();

        outputStream.write("   <select id=\"count" + name +  "\" parameterType=\"map\" resultType=\"int\">\n");
        outputStream.write("      SELECT count(*) from " + table);
        outputStream.write("   </select>");
        outputStream.newLine();

        outputStream.write("   <update id=\"update" + name + "\" parameterType=\"" + packages + "." + name + "\">\n");
        outputStream.write("      update " + table + " set \n");
        outputStream.write("       " + getSetProperties(key, column, properties) + "\n");
        outputStream.write("   </update>");
        outputStream.newLine();

        outputStream.write("   <delete id=\"delete" + name + "ById\" parameterType=\"long\">\n");
        outputStream.write("      delete from " + table + " where id=#{id}\n");
        outputStream.write("   </delete>");
        outputStream.newLine();

        outputStream.write("</mapper>");
        outputStream.newLine();
        outputStream.close();
        generateDao(name);
        generateService(name);
        generateController(name);
    }

    private String getPropertiesValue(String value) {
        if (StringUtil.isEmpty(value)) {
            return "";
        }
        String v[] = value.split("_");
        if (v.length == 1) {
            return v[0];
        }
        StringBuilder sb = new StringBuilder();
        sb.append(v[0]);
        for (int i = 1; i < v.length; i++) {
            sb.append(v[i].substring(0, 1).toUpperCase() + v[i].substring(1));
        }
        return sb.toString();
    }

    private String toStringList(List<String> list) {
        if (list.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            if (i > 0) {
                sb.append(",");
            }
            if("createTime".equals(list.get(i)) || "updateTime".equals(list.get(i))){
                sb.append("now()");
            }
            else {
                sb.append("#{" + list.get(i) + "}");
            }
        }
        return sb.toString();
    }

    private String toForeachStringList(List<String> list) {
        if (list.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            if (i > 0) {
                sb.append(",");
            }
            if("createTime".equals(list.get(i)) || "updateTime".equals(list.get(i))){
                sb.append("now()");
            }
            else {
                sb.append("#{ data." + list.get(i) + "}");
            }
        }
        return sb.toString();
    }

    private String getSetProperties(List<String> key, List<String> column, List<String> properties) {
        int index = key == null?0:key.size();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < column.size(); i++) {

            if("create_time".equals(column.get(i))){
                continue;
            }
            if(i > 0){
                sb.append(",");
            }
            if("update_time".equals(column.get(i))){
                sb.append(column.get(i) + "= now()");
            }else {
                sb.append(column.get(i) + "=" + "#{" + properties.get(i + index) + "}");
            }


        }
        sb.append("\n   where ");
        for (int i = 0; i < key.size(); i++) {
            if(i > 0){
                sb.append(",");
            }
            sb.append(key.get(i) + "=" + "#{" + properties.get(i) + "}");
        }
        String result = sb.toString();
        return result;
    }

    private String typeDif(String sqlType) {
        sqlType = sqlType.toUpperCase();
        if (sqlType.equals("FLOAT") || sqlType.equals("DOUBLE")) {
            return "double";
        } else if (sqlType.equals("DECIMAL")) {
            return "BigDecimal";
        } else if (sqlType.equals("BIGINT") || sqlType.equals("bigint")) {
            return "Long";
        } else if (sqlType.equals("TINYINT") || sqlType.equals("SMALLINT") || sqlType.equals("MEDIUMINT")
                || sqlType.equals("INT") || sqlType.equals("INTEGER") || sqlType.equals("BIT")) {
            return "int";
        } else if (sqlType.equals("DATE") || sqlType.equals("TIME") || sqlType.equals("YEAR") || sqlType.equals("DATETIME") ||
                sqlType.equals("TIMESTAMP")) {
            return "Date";
        }
        return "String";
    }

    private String getPackage(String packages) {
        if (packages == null || packages == "") {
            return null;
        }
        String path = packages.substring(packages.indexOf("java") + 5);
        path =  path.replace("\\", ".");
        return path.toString();
    }

    private class NamePair {
        public String key;
        public String value;

        public NamePair(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }

}
